package com.clock.service.impl;

import com.clock.common.constant.FollowCacheKey;
import com.clock.common.constant.HttpStatus;
import com.clock.common.domain.R;
import com.clock.common.exception.BizException;
import com.clock.common.utils.LocalDateTimeUtil;
import com.clock.common.utils.RedisUtil;
import com.clock.domain.dto.FollowStateDTO;
import com.clock.domain.dto.UserInfoDTO;
import com.clock.domain.entity.Follow;
import com.clock.mapper.FollowMapper;
import com.clock.service.FollowService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


@Service
public class FollowServiceImpl implements FollowService {


    @Resource
    FollowMapper followMapper;

    private final Integer NORMAL_SUCCESS = 1;

    private final Integer CANCEL_FOLLOW = 0;

    /**
     * 更新好友关注的状态信息
     *
     * @param followStateDto
     * @return
     */
    @Override
    public R updateFollowState(FollowStateDTO followStateDto) {
        // 非空判断
        if (followStateDto.getFollowUserId() == null) {
            throw new BizException(HttpStatus.BAD_REQUEST, "请选择关注人");
        }
        if (followStateDto.getIsFollowed() == 0 && followStateDto.getFollowAction() == 0) {
            throw new BizException(HttpStatus.BAD_REQUEST, "关注异常");
        }


        Follow follow = null;

        if (followStateDto.getUserId() != null &&  followStateDto.getFollowUserId() != null) {
            follow = followMapper.selectFollowByByUserIdAndFollowUserId(followStateDto.getUserId(), followStateDto.getFollowUserId());
        }


        //获取当地时间
        LocalDateTime localDateTime = LocalDateTimeUtil.getLocalDateTime();
        Date date = LocalDateTimeUtil.LocalDateTimeToDate(localDateTime);

        //根据关注动作和关注状态判断关注行为
        try {
            String FOLLOW_CACHE_KEY = FollowCacheKey.FOLLOW_PRE_CACHE_KEY + followStateDto.getUserId();

            boolean isFollowed = followStateDto.getIsFollowed() != 0 || followStateDto.getIsFollowed() == null;
            if (follow == null) {
                //从未关注过
                if ((followStateDto.getIsFollowed() == 0||followStateDto.getIsFollowed() == null) && followStateDto.getFollowAction() == 1) {

                    // 1.isFollowed==0&&followAction==1——>首次关注
                    followStateDto.setCreateTime(date);
                    followStateDto.setIsFollowed(1);
                    followMapper.insertFollow(followStateDto);
                    Follow newFollow = followMapper.selectFollowByUserIdAndCreateTime(followStateDto.getUserId(), followStateDto.getCreateTime());

                    if (newFollow == null) {
                        throw new BizException(HttpStatus.NOT_MODIFIED, "关注失败");
                    }


                    return R.ok("关注成功");

                }
            } else {
                if (followStateDto.getIsFollowed() == 0 && followStateDto.getFollowAction() == 1) {
                    // 2.isFollowed==0&&followAction==1——>重新关注
                    followStateDto.setUpdateTime(date);
                    followStateDto.setIsFollowed(1);
                    followMapper.updateFollowState(followStateDto);

                    Follow newFollow = followMapper.selectFollowByUserIdAndUpdateTime(followStateDto.getUserId(), followStateDto.getUpdateTime());

                    if (CANCEL_FOLLOW.equals(newFollow.getIsFollowed())) {
                        throw new BizException(HttpStatus.NOT_MODIFIED, "关注失败");
                    }


                    return R.ok("关注成功");


                } else if (followStateDto.getIsFollowed() == 1 && followStateDto.getFollowAction() == 0) {
                    // 2.isFollowed==1&&followAction==0——>取消关注
                    followStateDto.setUpdateTime(date);
                    followStateDto.setIsFollowed(0);
                    followMapper.updateFollowState(followStateDto);

                    Follow newFollow = followMapper.selectFollowByUserIdAndUpdateTime(followStateDto.getUserId(), followStateDto.getUpdateTime());

                    if (NORMAL_SUCCESS.equals(newFollow.getIsFollowed())) {
                        throw new BizException(HttpStatus.NOT_MODIFIED, "取关失败");
                    }


                    return R.ok("取关成功");
                }
            }

        } catch (Exception e) {

            throw new BizException(HttpStatus.NOT_MODIFIED, "操作失败");

        }

        return R.ok("操作成功");


    }


    /**
     * 好友关注展示列表 展示该用户id的所有正常关注的用户
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public R showFollows(Long userId, Integer pageNum, Integer pageSize) throws Exception {

        if (userId == null) {
            throw new BizException("参数异常");
        }

        PageInfo pageInfo;
        try {
            Set<Long> ids = followMapper.selectFollowsByUserId(userId);

            if (ids == null || ids.isEmpty()) {
                return R.ok(HttpStatus.NO_CONTENT, "暂无好友");
            }
            //通过ids查关注好友信息
            PageHelper.startPage(pageNum, pageSize);
            List<UserInfoDTO> followers = followMapper.queryFollowsInfoByIds(ids);
            pageInfo = new PageInfo(followers);

        } catch (DataAccessException e) {
            throw new BizException(HttpStatus.ERROR, "查询失败");
        }


        return R.ok(pageInfo);

    }

    /**
     * 查询粉丝信息
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public R getFans(Long userId, Integer pageNum, Integer pageSize) throws Exception {

        if (userId == null || pageNum == null || pageSize == null) {
            throw new BizException(HttpStatus.BAD_REQUEST, "请求参数错误");
        }
        try {
            PageHelper.startPage(pageNum, pageSize);
            List<UserInfoDTO> userInfos = followMapper.queryFansInfos(userId);
            if (userInfos == null) {
                return R.ok("暂无粉丝");
            }
            PageInfo pageInfo = new PageInfo(userInfos);
            return R.ok(pageInfo);
        } catch (Exception e) {
            return R.ok("暂无粉丝");
        }

    }




}
